package com.sas.domain;

import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

import org.hibernate.annotations.NaturalId;
import org.springframework.util.Assert;

@Entity
public class Article extends PersistentEntity {
	
	@Column(nullable = false)
	@NaturalId
	private String code;
	
	@Column(nullable = false)
	private String name;
	
	private String description;
	private Double weight;
	private Double netWeight;
	private Double height;
	private Double width;
	private Double priceBuy;
	private Double priceSell;
	
	@ManyToMany(cascade = CascadeType.ALL)
	private Set<ArticleField> fields;
	
	@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
	private Set<Vendor> vendors;
	
	@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
	private Set<Stock> stocks;
	
	@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
	private Set<Flow> flows;

	@OneToMany(fetch = FetchType.LAZY)
	@JoinColumn(name = "articleId")
	private List<Image> pictures;
	
	Article () {
	}
		
	public Article (String code, String name, String description, Double weight, Double netWeight,
			Double height, Double width, Double priceSell) {
		setCode(code);
		setName(name);
		setDescription(description);
		setWeight(weight);
		setNetWeigth(netWeight);
		setHeight(height);
		setWidth(width);
		setPriceSell(priceSell);
		setPriceBuy(new Double(0.0));
	}
	

	public String getCode() {
		return code;
	}

	public void setCode(String code) {		
		Assert.hasText(code);
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		Assert.hasText(name);
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		Assert.notNull(description);
		this.description = description;
	}

	public Double getWeight() {
		return weight;
	}

	public void setWeight(Double weight) {
		Assert.notNull(weight);
		Assert.state(weight >= 0.0);
		this.weight = weight;
	}

	public Double getNetWeigth() {
		return netWeight;
	}

	public void setNetWeigth(Double netWeigth) {
		Assert.notNull(netWeigth);
		Assert.state(netWeigth >= 0);
		this.netWeight = netWeigth;
	}

	public Double getHeight() {
		return height;
	}

	public void setHeight(Double height) {
		Assert.notNull(height);
		Assert.state(height >= 0);
		this.height = height;
	}

	public Double getWidth() {
		return width;
	}

	public void setWidth(Double width) {
		Assert.notNull(weight);
		Assert.state(width >= 0);
		this.width = width;
	}

	public Set<Vendor> getVendors() {
		return vendors;
	}

	public void setVendors(Set<Vendor> vendors) {
		Assert.notNull(vendors);
		this.vendors = vendors;
	}
	
	public List<Image> getPictures() {
		return this.pictures;
	}
	
	public void setPictures(List<Image> pictures) {
		Assert.notNull(pictures);
		this.pictures = pictures;
	}

	public void setFields(Set<ArticleField> fields) {
		Assert.notEmpty(fields);
		this.fields = fields;
	}

	public Set<ArticleField> getFields() {
		return fields;
	}

	public void setStocks(Set<Stock> stocks) {
		Assert.notNull(stocks);
		this.stocks = stocks;
	}

	public Set<Stock> getStocks() {
		return stocks;
	}

	public void setFlows(Set<Flow> flows) {
		Assert.notNull(flows);
		this.flows = flows;
	}

	public Set<Flow> getFlows() {
		return flows;
	}
	
	public Double getNetWeight() {
		return netWeight;
	}

	public void setNetWeight(Double netWeight) {
		this.netWeight = netWeight;
	}

	public Double getPriceBuy() {
		return priceBuy;
	}

	public void setPriceBuy(Double priceBuy) {
		this.priceBuy = priceBuy;
	}

	public Double getPriceSell() {
		return priceSell;
	}

	public void setPriceSell(Double priceSell) {
		this.priceSell = priceSell;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		result = prime * result
				+ ((description == null) ? 0 : description.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Article other = (Article) obj;
		if (code == null) {
			if (other.code != null)
				return false;
		} else if (!code.equals(other.code))
			return false;
		if (description == null) {
			if (other.description != null)
				return false;
		} else if (!description.equals(other.description))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	@Override
	public String toString() {
		return "[" + code + ", " + name + "]";
	}
}
